package com.ts.api.module.api.controller;

import com.gitee.apanlh.annotation.viewresolver.RequestParamVo;
import com.gitee.apanlh.util.base.Eq;
import com.gitee.apanlh.util.base.IteratorUtils;
import com.gitee.apanlh.util.valid.Assert;
import com.gitee.apanlh.web.model.vo.RequestVO;
import com.gitee.apanlh.web.model.vo.ResultVO;
import com.ts.api.common.constant.api.ApiEnum;
import com.ts.api.common.constant.api.ApiServiceCodeEnum;
import com.ts.api.common.constant.api.ApiVersionModeEnum;
import com.ts.api.exp.ApiMsgException;
import com.ts.api.module.api.entity.po.ApiKeyPO;
import com.ts.api.module.api.entity.vo.ReqApiParameterVO;
import com.ts.api.module.api.entity.vo.RespApiApplyQueryVO;
import com.ts.api.module.api.entity.vo.RespV2ApiApplyVO;
import com.ts.api.module.api.entity.vo.RespV2ApiDataExchangeVO;
import com.ts.api.module.api.entity.vo.RespV3ApiDataExchangePhoneMaskVO;
import com.ts.api.module.api.entity.vo.RespV3ApiDataExchangeVO;
import com.ts.api.module.api.handler.ApiMsgHandler;
import com.ts.api.module.api.service.ApiBizApplyNoticeService;
import com.ts.api.module.api.service.ApiMsgV1Service;
import com.ts.api.module.api.service.ApiMsgV2CallService;
import com.ts.api.module.api.service.ApiMsgV2Service;
import com.ts.api.module.api.service.ApiMsgV3Service;
import com.ts.api.module.match.plan.internal.distribute.model.PlanDistributePhoneMaskField;
import com.ts.api.module.product.entity.po.ProductPO;
import com.ts.api.module.product.entity.po.ProductPlanPO;
import com.ts.api.module.product.service.ProductPlanService;
import com.ts.api.module.product.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;

/**
 *  API消息控制层
 *
 *  @author Pan
 */
@RestController
@RequestMapping("/data/api")
public class ApiMsgController {

    @Autowired
    private ApiBizApplyNoticeService apiBizApplyNoticeService;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductPlanService productPlanService;
    @Autowired
    private ApiMsgHandler apiMsgHandler;
    @Autowired
    private ApiMsgV1Service apiMsgV1Service;
    @Autowired
    private ApiMsgV2Service apiMsgV2Service;
    @Autowired
    private ApiMsgV2CallService apiMsgV2CallService;
    @Autowired
    private ApiMsgV3Service apiMsgV3Service;

    /**
     *  v1-消息
     *
     *  @param  requestVO   请求视图
     *  @return ResultVO
     */
    @PostMapping("/msg")
    public ResultVO<Object> msg(@RequestParamVo RequestVO requestVO) throws Exception {
        //  解析撞库请求
        ReqApiParameterVO reqApiParameterVO = apiMsgHandler.handleDataExchangeRequest(requestVO);
        ApiServiceCodeEnum serviceCode = reqApiParameterVO.getServiceCode();
        ApiKeyPO apiKeyPO = reqApiParameterVO.getApiKeyPO();

        //  验证版本
        if (!ApiVersionModeEnum.MD5.hasVersionMode(apiKeyPO.getApiVersionMode())) {
            throw new ApiMsgException(ApiEnum.API_VERSION_MODE_ERROR);
        }

        //  撞库接口
        if (Eq.enums(ApiServiceCodeEnum.A0001, serviceCode)) {
            apiMsgV1Service.dataExchange(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg());
        }
        //  进件接口
        if (Eq.enums(ApiServiceCodeEnum.A0002, serviceCode)) {
            apiMsgV1Service.apply(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg());
        }
        //  默认返回失败处理
        return ResultVO.fail(ApiEnum.API_BIZ_CODE_ERROR.getCode(), ApiEnum.API_BIZ_CODE_ERROR.getMsg());
    }

    /**
     *  v2-上游-撞库-进件模式
     *
     *  @param  requestVO   请求视图
     *  @return ResultVO
     */
    @PostMapping("/v2/msg")
    public ResultVO<Object> v2Msg(@RequestParamVo RequestVO requestVO) throws Exception {
        //  解析撞库请求
        ReqApiParameterVO reqApiParameterVO = apiMsgHandler.handleDataExchangeRequest(requestVO);
        ApiServiceCodeEnum serviceCode = reqApiParameterVO.getServiceCode();
        ApiKeyPO apiKeyPO = reqApiParameterVO.getApiKeyPO();

        //  验证版本
        if (!ApiVersionModeEnum.MD5.hasVersionMode(apiKeyPO.getApiVersionMode())) {
            throw new ApiMsgException(ApiEnum.API_VERSION_MODE_ERROR);
        }

        //  撞库接口
        if (Eq.enums(ApiServiceCodeEnum.A0001, serviceCode)) {
            RespV2ApiDataExchangeVO respV2ApiDataExchangeVO = apiMsgV2Service.dataExchange(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respV2ApiDataExchangeVO);
        }

        //  进件接口
        if (Eq.enums(ApiServiceCodeEnum.A0002, serviceCode)) {
            RespV2ApiApplyVO respV2ApiApplyVO = apiMsgV2Service.apply(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respV2ApiApplyVO);
        }

        //  进件状态查询接口
        if (Eq.enums(ApiServiceCodeEnum.A0003, serviceCode)) {
            RespApiApplyQueryVO respApiApplyQueryVO = apiMsgV2Service.applyStatusQuery(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respApiApplyQueryVO);
        }
        //  默认处理
        return ResultVO.fail(ApiEnum.API_BIZ_CODE_ERROR.getCode(), ApiEnum.API_BIZ_CODE_ERROR.getMsg());
    }

    /**
     *  V2-撞库->回调页面->用户授权->接收进件申请授权->进件下游模式
     *
     *  @param  requestVO   请求视图
     *  @return ResultVO
     */
    @PostMapping("/v2/call/msg")
    public ResultVO<Object> v2CallMsg(@RequestParamVo RequestVO requestVO) throws Exception {
        //  解析撞库请求
        ReqApiParameterVO reqApiParameterVO = apiMsgHandler.handleDataExchangeRequest(requestVO);
        ApiServiceCodeEnum serviceCode = reqApiParameterVO.getServiceCode();
        ApiKeyPO apiKeyPO = reqApiParameterVO.getApiKeyPO();

        //  验证版本
        if (!ApiVersionModeEnum.MD5.hasVersionMode(apiKeyPO.getApiVersionMode())) {
            throw new ApiMsgException(ApiEnum.API_VERSION_MODE_ERROR);
        }

        //  撞库接口
        if (Eq.enums(ApiServiceCodeEnum.A0001, serviceCode)) {
            RespV2ApiDataExchangeVO respV2ApiDataExchangeVO = apiMsgV2CallService.dataExchange(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respV2ApiDataExchangeVO);
        }

        //  进件接口
        if (Eq.enums(ApiServiceCodeEnum.A0002, serviceCode)) {
            RespV2ApiApplyVO respV2ApiApplyVO = apiMsgV2CallService.apply(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respV2ApiApplyVO);
        }
        //  默认处理
        return ResultVO.fail(ApiEnum.API_BIZ_CODE_ERROR.getCode(), ApiEnum.API_BIZ_CODE_ERROR.getMsg());
    }

    /**
     *  V2手机号掩码模式-撞库->回调页面->用户授权->接收进件申请授权->进件下游模式
     *
     *  @param  requestVO   请求视图
     *  @return ResultVO
     */
    @PostMapping("/v2/call/phoneMask{maskLen}/msg")
    public ResultVO<Object> v2CallPhoneMaskMsg(@RequestParamVo RequestVO requestVO, @PathVariable Integer maskLen) throws Exception {
        //  解析撞库请求
        ReqApiParameterVO reqApiParameterVO = apiMsgHandler.handleDataExchangeRequest(requestVO);
        ApiServiceCodeEnum serviceCode = reqApiParameterVO.getServiceCode();
        ApiKeyPO apiKeyPO = reqApiParameterVO.getApiKeyPO();

        //  验证版本
        if (!ApiVersionModeEnum.PHONE_MASK_8.hasVersionMode(apiKeyPO.getApiVersionMode())) {
            throw new ApiMsgException(ApiEnum.API_VERSION_MODE_ERROR);
        }

        //  撞库接口
        if (Eq.enums(ApiServiceCodeEnum.A0001, serviceCode)) {
            RespV2ApiDataExchangeVO respV2ApiDataExchangeVO = apiMsgV2CallService.dataExchangePhoneMask(apiKeyPO, reqApiParameterVO, maskLen);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respV2ApiDataExchangeVO);
        }

        //  进件接口
        if (Eq.enums(ApiServiceCodeEnum.A0002, serviceCode)) {
            RespV2ApiApplyVO respV2ApiApplyVO = apiMsgV2CallService.applyPhoneMask(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respV2ApiApplyVO);
        }
        //  默认处理
        return ResultVO.fail(ApiEnum.API_BIZ_CODE_ERROR.getCode(), ApiEnum.API_BIZ_CODE_ERROR.getMsg());
    }

    /**
     *  V2(卖量下游-半流程-进件申请授权接口)，对方接入-回调授权通知-下游半流程回调通知
     *  我方提供-进件申请授权接口-接收下游回调通知，并且进件给下游(出量)
     *
     *  @param  requestVO   请求视图
     *  @param  productId   主体ID
     *  @return Map
     */
    @PostMapping("/v2/call/notice/{productId}")
    public Map<String, Object> applyCallNoticeV2(@RequestParamVo RequestVO requestVO, @PathVariable Long productId) {
        //  获取固定主体机构
        ProductPO productPO = productService.get(productId);
        Assert.isNotNullThrows(productPO, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("org", "主体id不可为null")));

        //  获取该主体下的计划-第一个计划
        List<ProductPlanPO> listPlan = productPlanService.listByProductId(productId);
        Assert.isNotEmptyThrows(listPlan, new ApiMsgException(ApiEnum.API_NULL_FAIL.format("plan", "计划id不可为null")));
        ProductPlanPO productPlanPO = IteratorUtils.getFirst(listPlan);

        //  拉取上游进件申请回调-并相应响应下游
        return apiBizApplyNoticeService.applyAcceptNotice(requestVO, productPO, productPlanPO);
    }

    /**
     *  v3-全流程接口
     *
     *  @param  requestVO   请求视图
     *  @return ResultVO
     */
    @PostMapping("/v3/msg")
    public ResultVO<Object> v3Msg(@RequestParamVo RequestVO requestVO) throws Exception {
        //  解析撞库请求
        ReqApiParameterVO reqApiParameterVO = apiMsgHandler.handleDataExchangeRequest(requestVO);
        ApiKeyPO apiKeyPO = reqApiParameterVO.getApiKeyPO();
        ApiServiceCodeEnum serviceCode = reqApiParameterVO.getServiceCode();

        //  验证版本
        if (!ApiVersionModeEnum.MD5.hasVersionMode(apiKeyPO.getApiVersionMode())) {
            throw new ApiMsgException(ApiEnum.API_VERSION_MODE_ERROR);
        }

        //  撞库接口
        if (Eq.enums(ApiServiceCodeEnum.A0001, serviceCode)) {
            RespV3ApiDataExchangeVO respV3ApiDataExchangeVO = apiMsgV3Service.dataExchange(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respV3ApiDataExchangeVO);
        }

        //  进件接口
        if (Eq.enums(ApiServiceCodeEnum.A0002, serviceCode)) {
            apiMsgV3Service.apply(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg());
        }

        //  进件状态查询接口
        if (Eq.enums(ApiServiceCodeEnum.A0003, serviceCode)) {
            RespApiApplyQueryVO respApiApplyQueryVO = apiMsgV3Service.applyStatusQuery(apiKeyPO, reqApiParameterVO);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), respApiApplyQueryVO);
        }

        //  用户授权文档信息接口
        if (Eq.enums(ApiServiceCodeEnum.A0004, serviceCode)) {
            //  返回进件结果状态
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg());
        }
        //  默认处理
        return ResultVO.fail(ApiEnum.API_BIZ_CODE_ERROR.getCode(), ApiEnum.API_BIZ_CODE_ERROR.getMsg());
    }

    /**
     *  v3-全流程手机号掩码模式接口
     *
     *  @param  requestVO   请求视图
     *  @return ResultVO
     */
    @PostMapping("/v3/msg/phoneMask{maskLen}")
    public ResultVO<Object> v3Msg(@RequestParamVo RequestVO requestVO, @PathVariable Integer maskLen) throws Exception {
        //  解析撞库请求
        ReqApiParameterVO reqApiParameterVO = apiMsgHandler.handleDataExchangeRequest(requestVO);
        ApiServiceCodeEnum serviceCode = reqApiParameterVO.getServiceCode();
        ApiKeyPO apiKeyPO = reqApiParameterVO.getApiKeyPO();

        //  验证版本
        if (!ApiVersionModeEnum.PHONE_MASK_8.hasVersionMode(apiKeyPO.getApiVersionMode())) {
            throw new ApiMsgException(ApiEnum.API_VERSION_MODE_ERROR);
        }

        //  撞库接口
        if (Eq.enums(ApiServiceCodeEnum.A0001, serviceCode)) {
            RespV3ApiDataExchangePhoneMaskVO respV3ApiDataExchangePhoneMaskVO = apiMsgV3Service.dataExchangePhoneMask(apiKeyPO, reqApiParameterVO, maskLen);
            //  返回成功匹配实体
            List<PlanDistributePhoneMaskField> listPlanDistributePhoneMaskField = respV3ApiDataExchangePhoneMaskVO.getListPlanDistributePhoneMaskField();
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg(), listPlanDistributePhoneMaskField);
        }

        //  进件接口
        if (Eq.enums(ApiServiceCodeEnum.A0002, serviceCode)) {
            apiMsgV3Service.applyPhoneMask(apiKeyPO, reqApiParameterVO, maskLen);
            return ResultVO.suc(ApiEnum.API_SIGN_SUC.getCode(), ApiEnum.API_SIGN_SUC.getMsg());
        }
        //  默认处理
        return ResultVO.fail(ApiEnum.API_BIZ_CODE_ERROR.getCode(), ApiEnum.API_BIZ_CODE_ERROR.getMsg());
    }
}
